 /**
 * @file tkl_network_manager.h
 * @brief Common process - network manager
 * @version 1.0.0
 * @date 2021-05-01
 *
 * @copyright Copyright 2021-2022 Tuya Inc. All Rights Reserved.
 *
 */

#ifndef __TKL_NETWORK_MANAGER_H__
#define __TKL_NETWORK_MANAGER_H__


#ifdef __cplusplus
    extern "C" {
#endif

#include "tuya_zigbee_stack.h"
#include "tuya_cloud_types.h"

/*
 * zigbee secret key type
*/
#define CENTRALIZED_GLOBAL_TC_LINK_KEY              0x00
#define DISTRIBUTED_SECURITY_GLOBAL_LINK_KEY        0x01
#define CENTRALIZED_INSTALL_CODE_DERIVED_LINK_KEY   0x02
#define DISTRIBUTED_TOUCHLINK_PRECFG_LINK_KEY       0x03

/*
 * zigbee network rejoin type
*/
typedef enum {
    // rejoin on current channel
    TKL_REJOIN_ON_CURRENT_CH = 0,
    // rejoin on all 802.25.4 channel(11~26)
    TKL_REJOIN_ON_ALL_ZG_CH,
} TKL_REJOIN_TYPE_E;

/*
 * zigbee secret key information structure
*/
typedef struct {
    UINT8_T nwk_key[16];         ///< encrypted network key
    UINT8_T sec_tc_link_key[16]; ///< security TC Link Key
} TKL_SECRET_KEY_T;
 
/*
 * zigbee install code structure
*/
typedef struct {
    UINT8_T code[16];           ///< install code 
} TKL_INSTALL_CODE_T;

/*
 * zigbee key status
*/
typedef enum {
    TKL_KEY_STATUS_NONE                 = 0x00,  ///< status none
    TKL_TCLINK_KEY_ESTABLISHED          = 0x02,  ///< receive TcLink key
    TKL_TCLINK_KEY_ESTABLISHED_FAILED   = 0x03,  ///< receive TcLink failed
    TKL_TCLINK_KEY_VERIFY_SUCCESS       = 0x04,  ///< verify TcLink key success
    TKL_TCLINK_KEY_VERIFY_FAILED        = 0x05,  ///< verify TcLink key failed
} TKL_KEY_STATUS_E;

typedef VOID_T (*TKL_TCLINK_KEY_CB)(TKL_KEY_STATUS_E status);

/*
 * zigbee network basic state
*/
typedef enum {
    // the node is not associated with a network in any way
    TKL_NODE_NO_NETWORK = 0,
    // the node is currently attempting to join a network
    TKL_NODE_JOINING_NETWORK,
    // the node is joined to a network
    TKL_NODE_JOINED_NETWORK,
    // the node is an end device joined to a network but its parent is not responding
    TKL_NODE_NO_PARENT,
    // the node is in the process of leaving its current network
    TKL_NODE_LEAVING_NETWORK
} TKL_NWK_BASIC_STATE_E;

typedef VOID_T (*TKL_ZGAL_NWK_CHANGE_CB)(TKL_NWK_BASIC_STATE_E state);

/*
 * zigbee scan type
*/
typedef enum {
    TKL_SCAN_FOR_JOIN = 0, ///< scan for joining a network
    TKL_SCAN_FOR_REJOIN    ///< scan for re-joining a network
} TKL_SCAN_TYPE_E;

/*
 * zigbee scan result
*/
typedef enum {
    TKL_SCAN_SUCESS = 0,    ///< scan success
    TKL_SCAN_NO_BEACONS,    ///< scan failed because no beacon received
    TKL_SCAN_NO_LINK_KEY,   ///< scan failed because no link key
    TKL_SCAN_DECRYPT_FAIL,  ///< scan failed because decrypt fail
    TKL_SCAN_NOT_PERMITTED, ///< scan failed because remote not permitted
    TKL_SCAN_UNKNOWN_FAIL,  ///< scan failed because other reasons
} TKL_SCAN_STATUS_E;

/*
 * zigbee basic information structure
*/
typedef struct {
    INT8_T   radio_power;   ///< radio power
    UINT8_T  radio_channel; ///< radio channel
    UINT16_T nwk_addr;      ///< network address,if not in network will be 0xFFFF
    UINT16_T panid;         ///< network panid,if not in network will be 0xFFFF
    UINT8_T  mac_addr[8];   ///< mac address
    UINT8_T  ext_panid[8];  ///< extend panid,if not in network will be all 0xFF
} TKL_NWK_BASIC_INFO_T;

/*
 * zigbee scan result structure
*/
typedef struct {
    UINT8_T channel;            ///< scan channel
    TKL_SCAN_TYPE_E type;       ///< scan type
    TKL_SCAN_STATUS_E result;   ///< scan result
} TKL_SCAN_RESULT_T;

/* 
 * zigbee join and rejoin complete callback
*/
typedef VOID_T (*TKL_NWK_SCAN_CB)(TKL_SCAN_RESULT_T *result);

/*
 * zigbee scan policy structure
*/
typedef struct {
    TKL_REJOIN_TYPE_E type;             ///< channel mask during scanning, specify one channel at a time
    TKL_NWK_SCAN_CB  scan_complete_cb;  ///< scan complete callback
} TKL_REJOIN_CFG_T;

/*
 * zigbee scan policy structure
*/
typedef struct {
    ZG_SCAN_DURATION_E  duration;           ///< scan duration for bdb
    UINT8_T             link_key_mask;      ///< the key used for data decryption during scanning
    UINT32_T            channel_mask;       ///< channel mask during scanning, specify one channel at a time
    TKL_NWK_SCAN_CB     scan_complete_cb;   ///< scan complete callback
} TKL_JOIN_CFG_T;

/*
 * zigbee scan policy structure
*/
typedef struct {
    union {
        TKL_JOIN_CFG_T   join;
        TKL_REJOIN_CFG_T rejoin;
    } scan;
} TKL_SCAN_POLICY_T;

/*
 * zigbee extern zigbee information
*/
typedef struct {
    UINT16_T profile_id;
    UINT16_T zg_device_id;
    UINT8_T  endpoint;
    UINT8_T  version;
}TKL_EXT_ZG_INFO_T;

/**
 * @brief get zigbee basic network information
 *
 * @param[in]   none
 * @return  NULL: fail  Other: success
 */
TKL_NWK_BASIC_STATE_E tkl_zg_nwk_base_status_get(VOID_T);

/**
 * @brief register network state change callback
 *
 * @param[in]   change callback: network change to notify app user
 * @return  OPRT_OK on success. Others on error, please refer to tuya_error_code.h
 */
OPERATE_RET tkl_zg_nwk_state_change_register(TKL_ZGAL_NWK_CHANGE_CB nwk_change_cb);

/**
 * @brief set zigbee scan policy
 *
 * @param[in]   type:   scan type
 * @param[in]   policy: point to the data structure of the set scan policy
 * @return  none
 */
VOID_T tkl_zg_scan_policy_set(TKL_SCAN_TYPE_E type, TKL_SCAN_POLICY_T *policy);

/**
 * @brief zigbee start scan
 *
 * @param[in]   type:   scan type
 * @return  OPRT_OK on success. Others on error, please refer to tuya_error_code.h
 */
OPERATE_RET tkl_zg_start_scan(TKL_SCAN_TYPE_E type);

/**
 * @brief zigbee stop scan
 *
 * @param[in]   type:   scan type
 * @return  OPRT_OK on success. Others on error, please refer to tuya_error_code.h
 */
OPERATE_RET tkl_zg_stop_scan(TKL_SCAN_TYPE_E type);

/**
 * @brief zigbee start leave
 *
 * @param[in]   none
 * @return  OPRT_OK on success. Others on error, please refer to tuya_error_code.h
 */
OPERATE_RET tkl_zg_start_leave(VOID_T);

/**
 * @brief set zigbee install code
 *
 * @param[in]   insall_code:    point to the data structure of install code
 * @return  none
 */
VOID_T tkl_zg_install_code_set(TKL_INSTALL_CODE_T *insall_code);

/**
 * @brief get zigbee install code
 *
 * @param[in]   insall_code:    point to the data structure of install code
 * @return  none
 */
VOID_T tkl_zg_install_code_get(TKL_INSTALL_CODE_T *insall_code);

/**
 * @brief get zigbee network secret key struct
 *
 * @param[in]   key_info:    point to the data structure of install code
 * @return  TRUE: success  Other: fail
 */
BOOL_T tkl_zg_nwk_secret_key_info_get(TKL_SECRET_KEY_T *key_info);

/**
 * @brief register key status callback
 *
 * @param[in]   key_cb:    key callback
 * @return  OPRT_OK on success. Others on error, please refer to tuya_error_code.h
 */
OPERATE_RET tkl_zg_register_key_establish_cb(TKL_TCLINK_KEY_CB key_cb);

/**
 * @brief enable broadcast permit join after joined network(default is disable)
 * NOTE: this interface needs to be enabled if ZigBee 3.0 authentication is performed
 *
 * @param[in]   enable: enable broadcast permit join
 * @return  none
 */
VOID_T tkl_zg_enable_permit_join_after_joined(BOOL_T enable);

/**
 * @brief get zigbee network basic information
 *
 * @param[in]   nwk_info:    point to the data structure of network basic information
 * @return  none
 */
VOID_T tkl_zg_nwk_base_info_get(TKL_NWK_BASIC_INFO_T *nwk_info);

/**
 * @brief get zigbee radio channel
 *
 * @param[in] none
 * @return radio channel
 */
UINT8_T tkl_zg_radio_channel_get(VOID_T);

/**
 * @brief set zigbee radio channel
 *
 * @param[in]   channel: radio channel
 * @return none
 */
VOID_T tkl_zg_radio_channel_set(UINT8_T channel);

/**
 * @brief get zigbee radio power
 *
 * @param[in] none
 * @return radio power
 */
INT8_T tkl_zg_radio_power_get(VOID_T);

/**
 * @brief set zigbee radio power
 *
 * @param[in]   tx_power:    radio power
 * @return  none
 */
VOID_T tkl_zg_radio_power_set(INT8_T tx_power);

/**
 * @brief get zigbee mac address
 *
 * @param[out]   mac:    mac address
 * @return  none
 */
VOID_T tkl_zg_mac_address_get(UINT8_T *mac);

/**
 * @brief get zigbee network short address
 *
 * @param[in] none
 * @return  network address
 */
UINT16_T tkl_zg_nwk_address_get(VOID_T);

/**
 * @brief get zigbee network panid
 *
 * @param[in] none
 * @return  network panid
 */
UINT16_T tkl_zg_nwk_panid_get(VOID_T);

/**
 * @brief get zigbee network extend panid
 *
 * @param[out] extpanid: extend panid
 * @return  none
 */
VOID_T tkl_zg_nwk_extend_panid_get(UINT8_T *extpanid);

/**
 * @brief zigbee network type get
 *
 * @param[in]   none
 * @return  0: success  Other: fail
 */
ZG_NWK_TYPE_E tkl_zg_nwk_type_get(VOID_T);

/**
 * @brief zigbee node type get
 *
 * @param[in]   none
 * @return  0: success  Other: fail
 */
ZG_NODE_TYPE_E tkl_zg_node_type_get(VOID_T);

/**
 * @brief zigbee node type set
 *
 * @param[in]   none
 * @return  0: success  Other: fail
 */
VOID_T tkl_zg_node_type_set(ZG_NODE_TYPE_E type);


/**
 * @brief custom specific max radio power in ch26
 * 
 * @param db 
 * @return OPERATE_RET 
 */
OPERATE_RET tkl_zg_ch26_power_max_db_set(INT8_T db);

/**
 * @brief set zigbee device extension information for special usage
 * 
 * @param p_zg_info 
 * @param sums 
 * @return BOOL_T 
 */
BOOL_T tkl_zg_set_ext_zg_info(TKL_EXT_ZG_INFO_T *p_zg_info, UINT8_T sums);

/**
 * @brief enable mandatory of only using installcode when join network (default is disable)
 * NOTE: None
 *
 * @param[in]   enable: enable only use installcode when join network
 * @return  none
 */
VOID_T tkl_zg_nwk_join_by_installcode_only_enable(BOOL_T enable);

#ifdef __cplusplus
}
#endif

#endif

